package com.zhiche.lisa.lspm.service.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.zhiche.lisa.core.supports.BaseException;
import com.zhiche.lisa.core.supports.RestfulResponse;
import com.zhiche.lisa.core.utils.HttpClientUtil;
import com.zhiche.lisa.lspm.vo.common.Account;
import com.zhiche.lisa.lspm.vo.common.AccountVO;
import com.zhiche.lisa.lspm.vo.lsp.LspTaxpayerTenantVO;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * Created by zhaoguixin on 2018/6/30.
 */
@Component
public class UaaUtil {

    @Value("${uaa.url}")
    private String uaaUrl;

    @Value("${uaa.socketTimeout}")
    private int socketTimeout;

    @Value("${uaa.tenantUpdateUrl}")
    private String tenantUpdateUrl;

    @Value("${uaa.getAccountByIdUrl}")
    private String getAccountByIdUrl;

    @Value("${uaa.updateMoblieUrl}")
    private String updateMoblieUrl;

    @Value("${uaa.lockedTenantUrl}")
    private String lockedTenantUrl;

    @Value("${uaa.unlockedTenantUrl}")
    private String unlockedTenantUrl;

    @Value("${uaa.listAdminAccountByTenantUrl}")
    private String listAdminAccountByTenantUrl;


    @Value("${security.oauth2.client.access-token-uri}")
    private String getTokenUrl;

    @Value("${uaa.getListAdminAccountUrl}")
    private String getListAdminAccountUrl;


    @Value("${security.oauth2.client.clientId}")
    private String getClinetId;

    @Value("${security.oauth2.client.clientSecret}")
    private String getClientSecret;

    public RestfulResponse<Account> signup(String mail, String mobile, String password, String authorization, Long tenantId) {
        List<NameValuePair> urlHeaders = new ArrayList<>();
        urlHeaders.add(new BasicNameValuePair("Authorization", authorization));
        List<NameValuePair> headNamePairs = Lists.newArrayList();
        String signupUrl = uaaUrl + "/tenant/account/create";
        Map<String, String> parmsMap = new HashMap<>();
        parmsMap.put("mail", mail);
        parmsMap.put("mobile", mobile);
        parmsMap.put("password", password);
        parmsMap.put("tenantId", tenantId.toString());
        String parmsJson = JSON.toJSONString(parmsMap);
        String strReturn = HttpClientUtil.postJson(signupUrl, urlHeaders, parmsJson, socketTimeout);
        if (!StringUtils.isEmpty(strReturn)) {
            RestfulResponse<Account> restfulResponse = JSON.parseObject(strReturn, new TypeReference<RestfulResponse<Account>>() {
            });
            return restfulResponse;
        } else {
            return null;
        }
    }

    public RestfulResponse<Boolean> lockAccount(String accountId, String token) {
        List<NameValuePair> headNamePairs = Lists.newArrayList();
        String lockAccountUrl = uaaUrl + "/account/lockAccount";
        headNamePairs.add(new BasicNameValuePair("Authorization", token));
//        List<NameValuePair> params = Lists.newArrayList();
//        params.add(new BasicNameValuePair("accountId",accountId));

        Map<String, String> params = new HashMap<>();
        params.put("accountId", accountId);

        String strReturn = HttpClientUtil.post(lockAccountUrl, headNamePairs, params, socketTimeout);
        if (!StringUtils.isEmpty(strReturn)) {
            RestfulResponse<Boolean> restfulResponse = JSON.parseObject(strReturn, new
                    TypeReference<RestfulResponse<Boolean>>() {
                    });
            return restfulResponse;
        } else {
            return null;
        }
    }
    public RestfulResponse<Boolean> lockedTenant(String tenantId, String token) {
        List<NameValuePair> headNamePairs = Lists.newArrayList();
        String lockAccountUrl = uaaUrl + lockedTenantUrl;
        headNamePairs.add(new BasicNameValuePair("Authorization", token));
        Map<String, String> params = new HashMap<>();
        params.put("tenantId", tenantId);
        String strReturn = HttpClientUtil.post(lockAccountUrl, headNamePairs, params, socketTimeout);
        if (!StringUtils.isEmpty(strReturn)) {
            RestfulResponse<Boolean> restfulResponse = JSON.parseObject(strReturn, new
                    TypeReference<RestfulResponse<Boolean>>() {
                    });
            return restfulResponse;
        } else {
            return null;
        }
    }

    public RestfulResponse<Boolean> unlockAccount(String accountId, String token) {
        List<NameValuePair> headNamePairs = Lists.newArrayList();
        String lockAccountUrl = uaaUrl + "/account/unlockAccount";
        headNamePairs.add(new BasicNameValuePair("Authorization", token));
//        List<NameValuePair> params = Lists.newArrayList();
//        params.add(new BasicNameValuePair("accountId",accountId));
        Map<String, String> params = new HashMap<>();
        params.put("accountId", accountId);
        String strReturn = HttpClientUtil.post(lockAccountUrl, headNamePairs, params, socketTimeout);
        if (!StringUtils.isEmpty(strReturn)) {
            RestfulResponse<Boolean> restfulResponse = JSON.parseObject(strReturn, new
                    TypeReference<RestfulResponse<Boolean>>() {
                    });
            return restfulResponse;
        } else {
            return null;
        }
    }

    public RestfulResponse<Boolean> unlockedTenant(String tenantId, String token) {
        List<NameValuePair> headNamePairs = Lists.newArrayList();
        String lockAccountUrl = uaaUrl + unlockedTenantUrl;
        headNamePairs.add(new BasicNameValuePair("Authorization", token));
        Map<String, String> params = new HashMap<>();
        params.put("tenantId", tenantId);
        String strReturn = HttpClientUtil.post(lockAccountUrl, headNamePairs, params, socketTimeout);
        if (!StringUtils.isEmpty(strReturn)) {
            RestfulResponse<Boolean> restfulResponse = JSON.parseObject(strReturn, new
                    TypeReference<RestfulResponse<Boolean>>() {
                    });
            return restfulResponse;
        } else {
            return null;
        }
    }

    public Account getLoginAccount() {
        String accountNo = getLoginAccountNo();
//        List<NameValuePair> headNamePairs = Lists.newArrayList();
        String signupUrl = uaaUrl + "/account/getAccount";
        List<NameValuePair> params = Lists.newArrayList();
        params.add(new BasicNameValuePair("identifier", accountNo));
        String strReturn = HttpClientUtil.get(signupUrl, null, params, socketTimeout);
        if (!StringUtils.isEmpty(strReturn)) {
            RestfulResponse<Account> restfulResponse = JSON.parseObject(strReturn, new TypeReference<RestfulResponse<Account>>() {
            });
            if (restfulResponse.getCode() == 0) {
                return restfulResponse.getData();
            } else {
                return null;
            }
        } else {
            return null;
        }
    }

    public String getLoginAccountNo() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String accountNo = authentication.getPrincipal().toString();
        return accountNo;
    }

    public Long createTenant(String repMobile, String corpName, String taxpayerId, String authorization) {
        List<NameValuePair> headNamePairs = Lists.newArrayList();
        headNamePairs.add(new BasicNameValuePair("Authorization", authorization));
        Map<String, String> params = new HashMap<>();
        params.put("mobile", repMobile);
        params.put("password", "123456");
        params.put("corpName", corpName);
        if (!Strings.isNullOrEmpty(taxpayerId)) params.put("taxpayerId", taxpayerId);
        String parmsJson = JSON.toJSONString(params);
        JSONObject obj = JSON.parseObject(HttpClientUtil.postJson(uaaUrl + "/tenant/create", headNamePairs, parmsJson, socketTimeout));
        String retCode = obj.getString("code");
        String message = obj.getString("message");
        if (Strings.isNullOrEmpty(retCode)) throw new BaseException("创建租户信息出错");
        if (!retCode.equals("0")) throw new BaseException(message);
        return obj.getJSONObject("data").getLong("id");
    }

    public void updateCorpName(Long tenantId, String corpName, String authorization) {
        List<NameValuePair> headNamePairs = Lists.newArrayList();
        headNamePairs.add(new BasicNameValuePair("Authorization", authorization));
        Map<String, String> params = new HashMap<>();
        params.put("corpName", corpName);
        params.put("id", tenantId.toString());
        String parmsJson = JSON.toJSONString(params);
        JSONObject obj = JSON.parseObject(HttpClientUtil.postJson(uaaUrl + "/tenant/update/basicinfo", headNamePairs, parmsJson, socketTimeout));
        String retCode = obj.getString("code");
        String message = obj.getString("message");
        if (Strings.isNullOrEmpty(retCode)) throw new BaseException("修改匹配租户信息出错");
        if (!retCode.equals("0")) throw new BaseException(message);
    }

    public String getTenantToken(String techAccountIdentifier) {
        Map<String, String> parmers = Maps.newHashMap();
        parmers.put("username", techAccountIdentifier);
        parmers.put("password", "123456");
        parmers.put("client_id", getClinetId);
        parmers.put("client_secret", getClientSecret);
        parmers.put("grant_type", "password");
        String result = HttpClientUtil.post(getTokenUrl, parmers, socketTimeout);
        if (StringUtils.isEmpty(result)) return null;
        JSONObject jsonObject2 = JSON.parseObject(result);
        if (Objects.nonNull(jsonObject2)) {
            String access_token = jsonObject2.getString("access_token");
            return "Bearer " + access_token;
        } else {
            return null;
        }
    }

    /**
     * 根据用户id获取账户信息
     * @param accountId
     * @param authorization
     * @return
     */

    public AccountVO getAccountById(String accountId,String authorization) {
        List<NameValuePair> headNamePairs = Lists.newArrayList();
        String lockAccountUrl = getAccountByIdUrl;
        headNamePairs.add(new BasicNameValuePair("Authorization", authorization));
        List<NameValuePair> params = Lists.newArrayList();
        params.add(new BasicNameValuePair("accountId", accountId));
        String strReturn = HttpClientUtil.get(lockAccountUrl,headNamePairs, params, socketTimeout);
        if (!StringUtils.isEmpty(strReturn)) {
            RestfulResponse<AccountVO> restfulResponse = JSON.parseObject(strReturn, new
                    TypeReference<RestfulResponse<AccountVO>>() {
                    });
            if (restfulResponse.getCode() == 0) {
                return restfulResponse.getData();
            } else {
                return null;
            }
        } else {
            return null;
        }
    }

    /**
     * 获取当前用户所属租户的管理员账号
     * @param authorization
     * @return
     */
    public List<AccountVO> getListAdminAccountUrl(String authorization) {
        List<NameValuePair> headNamePairs = Lists.newArrayList();
        String lockAccountUrl = uaaUrl+getListAdminAccountUrl;
        headNamePairs.add(new BasicNameValuePair("Authorization", authorization));
        String strReturn = HttpClientUtil.get(lockAccountUrl,headNamePairs, Lists.newArrayList(), socketTimeout);
        if (!StringUtils.isEmpty(strReturn)) {
            RestfulResponse<List<AccountVO>> restfulResponse = JSON.parseObject(strReturn, new
                    TypeReference<RestfulResponse<List<AccountVO>>>() {
                    });
            if (restfulResponse.getCode() == 0) {
                return restfulResponse.getData();
            } else {
                return null;
            }
        } else {
            return null;
        }
    }

    /**
     * 更新租户信息
     * @param tenantVO
     * @param authorization
     * @return
     */
    public void tenantUpdateUrl(LspTaxpayerTenantVO tenantVO, String authorization) {
        List<NameValuePair> headNamePairs = Lists.newArrayList();
        String lockAccountUrl = uaaUrl+tenantUpdateUrl;
        headNamePairs.add(new BasicNameValuePair("Authorization", authorization));
        String parmsJson = JSON.toJSONString(tenantVO);
        String strReturn = HttpClientUtil.postJson(lockAccountUrl,headNamePairs, parmsJson, socketTimeout);
        if (!StringUtils.isEmpty(strReturn)) {
            RestfulResponse<Boolean> restfulResponse = JSON.parseObject(strReturn, new
                    TypeReference<RestfulResponse<Boolean>>() {
                    });
            if (restfulResponse.getCode() != 0) throw new BaseException(restfulResponse.getMessage());
        }
    }

    /**
     * 获取账户的手机号
     * @param accountId
     * @param mobile
     * @param token
     * @return
     */
    public RestfulResponse<Boolean> updateMoblie(Long accountId,String mobile, String token) {
        List<NameValuePair> headNamePairs = Lists.newArrayList();
        String lockAccountUrl = uaaUrl + updateMoblieUrl;
        headNamePairs.add(new BasicNameValuePair("Authorization", token));
        Map<String, String> params = new HashMap<>();
        params.put("accountId", accountId.toString());
        params.put("mobile", mobile);
        String strReturn = HttpClientUtil.post(lockAccountUrl, headNamePairs, params, socketTimeout);
        if (!StringUtils.isEmpty(strReturn)) {
            RestfulResponse<Boolean> restfulResponse = JSON.parseObject(strReturn, new
                    TypeReference<RestfulResponse<Boolean>>() {
                    });
            if(Objects.nonNull(restfulResponse)){
                if (restfulResponse.getCode() != 0) throw new BaseException(restfulResponse.getMessage());
            }
            return restfulResponse;
        } else {
            return null;
        }
    }

    /**
     * 获取租户所有的管理员账号
     *
     * @param authorization
     * @return
     */
    public List<AccountVO> getListTenantAccount(Long tenantId, String authorization) {
        List<NameValuePair> headNamePairs = Lists.newArrayList();
        headNamePairs.add(new BasicNameValuePair("Authorization", authorization));
        List<NameValuePair> paramNamePairs = Lists.newArrayList();
        paramNamePairs.add(new BasicNameValuePair("tenantId", tenantId.toString()));
        String strReturn = HttpClientUtil.get(uaaUrl + listAdminAccountByTenantUrl, headNamePairs, paramNamePairs, socketTimeout);
        if (!StringUtils.isEmpty(strReturn)) {
            RestfulResponse<List<AccountVO>> restfulResponse = JSON.parseObject(strReturn, new
                    TypeReference<RestfulResponse<List<AccountVO>>>() {
                    });
            if (restfulResponse.getCode() == 0) {
                return restfulResponse.getData();
            } else {
                return null;
            }
        } else {
            return null;
        }
    }

}
